package com.gxljc.bear.crawler.itaogao.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.gxljc.bear.crawler.weixin.WeixinConst;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.gxljc.commons.mongo.cli.BaseMongoRepository;
import com.gxljc.commons.util.StringUtil;
import com.gxljc.bear.crawler.base.BaseMongoTools;
import com.gxljc.bear.crawler.base.DolphinCrawlerConsts;
import com.gxljc.bear.crawler.itaogao.NewsPageTable;

/**
 * Created by Administrator on 2016/9/9.>>haitao
 */
public class MongodbUtil {
    private static BaseMongoRepository repo;
    private final static Logger LOG = Logger.getLogger(MongodbUtil.class);

    //save data to mongodb
    public static void saveMongodb(List<NewsPageTable> tables, String tableName) throws Exception {
        if (CollectionUtils.isEmpty(tables)) return;
        for (NewsPageTable table : tables) {
            saveMongodb(table, tableName);
        }
    }

    //save data to mongodb
    public static void saveMongodb(NewsPageTable table, String tableName) throws Exception {
        Query query = new Query();
        query.addCriteria(Criteria.where(DolphinCrawlerConsts.MONGODB_DEFAULT_ID).is(table.id));
        Update update = new Update();
        Field[] fields = table.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Object value = fields[i].get(table);
            if (value == null) continue;
            if (value instanceof List) {
                if (CollectionUtils.isEmpty((List) value)) continue;
            }
            if (value instanceof String) {
                if (StringUtils.isEmpty((String) value)) continue;
            }
            update.set(fields[i].getName(), value);
        }
        BaseMongoRepository repo = BaseMongoTools.getInstance(DolphinCrawlerConsts.MongoDBName.ITAOGAO.getName());
        repo.upsert(query, update, tableName);
    }


    /**
     * 判别url是否需要重爬,即查询mongdb是否存在该url记录
     *
     * @param url
     * @return
     */
    public static boolean needReCrawl(String url, String collectionName) {
        repo = BaseMongoTools.getInstance(DolphinCrawlerConsts.MongoDBName.ITAOGAO.getName());
        boolean flag = false;
        if (!url.isEmpty()) {
            String _id = StringUtil.genMD5Val(url);
            Query query = new Query();
            query.addCriteria(Criteria.where("_id").is(_id));
            flag = repo.doExist(query, collectionName);

        }
        return flag;
    }

    /**
     * 更新到mongodb中去
     *
     * @param map
     * @param collectionName
     */
    public static void update2Mongodb(Map<String, Object> map, String collectionName) {
        repo = BaseMongoTools.getInstance(DolphinCrawlerConsts.MongoDBName.ITAOGAO.getName());
        List<String> failAid = new ArrayList<>();
        try {
            Query query = new Query();
            String _id = map.get("_id").toString();
            query.addCriteria(Criteria.where("_id").is(_id));
            Update update = new Update();
            for (Entry<String, Object> entry : map.entrySet()) {
                update.set(entry.getKey(), entry.getValue());
            }
            repo.upsert(query, update, collectionName);
        } catch (Exception e) {
            failAid.add(map.get("_id").toString());
            LOG.error("insert or update error of " + map.get("_id").toString(), e);
        }
    }

    public static void failTime(NewsPageTable table, String tableName) {
        Integer failTime = table.getFailTime();
        if (failTime == null) failTime = 1;
        else failTime = failTime.intValue() + 1;
        if (failTime.intValue() < WeixinConst.MAX_WEIXIN_PAGE_FAIL_TIME) {
            NewsPageTable newTable = new NewsPageTable();
            newTable.setId(table.id);
            newTable.setFailTime(failTime);
            try {
                saveMongodb(newTable, tableName);
            } catch (Exception e) {
                e.printStackTrace();
                LOG.error("save page fail time error = " + table.id);
            }
        } else {
            try {
                NewsPageTable newTable = new NewsPageTable();
                newTable.setId(table.id);
                newTable.setCrawlFlag(DolphinCrawlerConsts.RESULT_YES);
                saveMongodb(newTable, tableName);
            } catch (Exception e) {
                e.printStackTrace();
                LOG.error("pageid error = " + table.id);
            }
        }
    }
}
